package com.zz.framework.core.utils

import android.Manifest.permission.*
import android.annotation.SuppressLint
import android.content.Context
import android.content.Context.WIFI_SERVICE
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.net.wifi.WifiManager
import android.util.Log
import androidx.annotation.RequiresPermission
import com.zz.framework.core.BaseApp
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader


/**
 * Copyright © 2019 zanezhao All rights reserved.
 * Created by zanezhao on 2019-11-13 17:02.
 * @author: zanezhao 1820022519@qq.com
 * @version: V1.0
 */
class NetWorkUtils {
    private fun NetWorkUtils(): NetWorkUtils {
        throw UnsupportedOperationException("u can't instantiate me...")
    }

    companion object {

        fun isNetworkAvailable(context: Context): Boolean {
            val manager = context.applicationContext.getSystemService(
                Context.CONNECTIVITY_SERVICE
            ) as ConnectivityManager
            val info = manager.activeNetworkInfo
            return !(null == info || !info.isAvailable)
        }


        /**
         * Return whether network is connected.
         *
         * Must hold
         * `<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />`
         *
         * @return `true`: connected<br></br>`false`: disconnected
         */
        @RequiresPermission(ACCESS_NETWORK_STATE)
        fun isConnected(): Boolean {
            val info = getActiveNetworkInfo()
            return info != null && info.isConnected
        }

        /**
         * Return whether using mobile data.
         *
         * Must hold
         * `<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />`
         *
         * @return `true`: yes<br></br>`false`: no
         */
        @RequiresPermission(ACCESS_NETWORK_STATE)
        fun isMobileData(): Boolean {
            val info = getActiveNetworkInfo()
            return (null != info
                    && info.isAvailable
                    && info.type == ConnectivityManager.TYPE_MOBILE)
        }


        /**
         * Return whether wifi is enabled.
         *
         * Must hold
         * `<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />`
         *
         * @return `true`: enabled<br></br>`false`: disabled
         */
        @RequiresPermission(ACCESS_WIFI_STATE)
        fun getWifiEnabled(): Boolean {
            @SuppressLint("WifiManagerLeak")
            val manager = BaseApp.context.getSystemService(WIFI_SERVICE) as WifiManager
                ?: return false
            return manager.isWifiEnabled
        }

        /**
         * Set wifi enabled.
         *
         * Must hold
         * `<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />`
         *
         * @param enabled True to enabled, false otherwise.
         */
        @RequiresPermission(CHANGE_WIFI_STATE)
        fun setWifiEnabled(enabled: Boolean) {
            @SuppressLint("WifiManagerLeak")
            val manager = BaseApp.context.getSystemService(WIFI_SERVICE) as WifiManager
                ?: return
            if (enabled == manager.isWifiEnabled) return
            manager.isWifiEnabled = enabled
        }

        /**
         * Return whether wifi is connected.
         *
         * Must hold
         * `<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />`
         *
         * @return `true`: connected<br></br>`false`: disconnected
         */
        @RequiresPermission(ACCESS_NETWORK_STATE)
        fun isWifiConnected(): Boolean {
            val cm =
                BaseApp.context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                    ?: return false
            val ni = cm.activeNetworkInfo
            return ni != null && ni.type == ConnectivityManager.TYPE_WIFI
        }


        @RequiresPermission(ACCESS_NETWORK_STATE)
        private fun getActiveNetworkInfo(): NetworkInfo? {
            val cm =
                BaseApp.context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                    ?: return null
            return cm.activeNetworkInfo
        }


        /*
        * @category 判断是否有外网连接（普通方法不能判断外网的网络是否连接，比如连接上局域网）
        * @return
        */
        suspend fun ping(): Boolean {
            var result: String? = null
            try {
                val ip = "www.baidu.com" // ping 的地址，可以换成任何一种可靠的外网
                val p = Runtime.getRuntime().exec("ping -c 3 -w 100 $ip") // ping网址3次
                // 读取ping的内容，可以不加
                val input: InputStream = p.inputStream
                val `in` = BufferedReader(InputStreamReader(input))
                val stringBuffer = StringBuffer()
                var content: String? = ""
                while (`in`.readLine().also({ content = it }) != null) {
                    stringBuffer.append(content)
                }
                Log.d("------ping-----", "result content : $stringBuffer")
                // ping的状态
                val status = p.waitFor()
                if (status == 0) {
                    result = "success"
                    return true
                } else {
                    result = "failed"
                }
            } catch (e: IOException) {
                result = "IOException"
            } catch (e: InterruptedException) {
                result = "InterruptedException"
            } finally {
                Log.d("----result---", "result = $result")
            }
            return false
        }
    }
}